<?php
require_once( APPLICATION_PATH  . "/papi/services/services/ProductTemplate.php");

/**
 * Api para administrar los productos personalizados
 * 
 * Con esta api, se podra crear, actualizar u obtener info sobre un producto personalizado
 *
 */
class PapiWS_Service_PersonalizedProduct
{

	/**
	 * Crear un producto vacia a partir de un templateId
	 *  
	 * @param  int $templateProductId El ID del template a usar para crear el prodcto 
	 * @return mixed devuelve el producto creado como un PersonalizedProductVO
	 */
	public function createProduct( $templateProductId  ) 
	{
		// validar templateProductId
		if ( $templateProductId == null || 
			(int) $templateProductId == 0 ) {
			throw new Ext_Exception( 'El templateID está null o no es válido.' );
		}

		$productTemplate = new PapiWS_Service_ProductTemplate();
		$productTemplateInfo = $productTemplate->getInfo( $templateProductId );
		if( ! isset( $productTemplateInfo->id )) {
			throw new Ext_Exception( 'El template no existe!' );
		}

		return $this->createProductFromTemplate( $productTemplateInfo );
	}

	/**
	 * Crear un producto vacia a partir de un template
	 *  
	 * @param  int $templateProduct El objeto ProductTemplateVO 
	 * @return mixed devuelve el producto creado como un PersonalizedProductVO
	 */
	public function createProductFromTemplate( $templateProduct  ) 
	{
		// validar templateProductId
		if ( $templateProduct == null ) {
			throw new Ext_Exception( 'El templateID está null o no es válido.' );
		}

		// armamos el PersonalizedProductVO
		$prod = new PapiWS_Model_PersonalizedProductVO();
		$prod->name = '';
		$prod->templateProduct = $templateProduct;
		$prod->templateProductId = $templateProduct->id;
		$prod->faces = array();
		foreach( $templateProduct->faces as $face ) {
			$prod->faces[] = new PapiWS_Model_PersonalizedFaceVO();
		}

		$personalizedProductId = $this->_initPersonalizedProduct( $prod );
		$prod->personalizedProductId = $personalizedProductId;

		return $prod;
	}

	/**
	 *	Obtiene la info de un producto
	 *
	 *	Obtiene la info de un producto a partir del personalized Product
	 *
	 * @param int $personalizedProductId Id del producto personalizado
	 * @return mixed VO del producto personalizado
	 */
	public function getProduct( $personalizedProductId ) 
	{
		$ppmodel = new PapiWS_Model_PersonalizedProduct();
		$row = $ppmodel->find( $personalizedProductId )->current();
		if( count( $row )) {
			$ppVo = unserialize( $row['object'] );
			//print_r($ppVo);die('getProduct');
			$ppVo->personalizedProductId = $personalizedProductId;
			return $ppVo;
		}
		throw new Ext_Exception( 'No se encontró el producto con id: ' . $personalizedProductId);
	}

	public function createCustomNotebook( $width, $height ) {
	
		// armamos el PersonalizedProductVO
		$prod = new PapiWS_Model_PersonalizedProductVO();
		$prod->name = 'Notebook tamaño variable.';
		$prod->templateProduct = $productTemplateInfo;
		$prod->templateProductId = $templateProductId;

		// armamos el template
		$tplService = new PapiWS_Service_ProductTemplate();
		$prod->templateProduct = $tplService->createCustomNotebookTemplate($width, $height);

		// le ponemos una cara
		$prod->faces = array();
		$prod->faces[] = new PapiWS_Model_PersonalizedFaceVO();

		$personalizedProductId = $this->_initPersonalizedProduct( $prod );
		$prod->personalizedProductId = $personalizedProductId;

		return $prod;
	}

	/**
	 * 
	 * Guarda el producto 
	 * 
	 * Persiste el producto pasado como un VO
	 * 
	 * @param PapiWS_Model_PersonalizedProductVO $personalizedProductVO Vo del producto
	 * @return true si se graba exitosamente o una excepcion si hay errores.
	 */
	public function saveProduct( $personalizedProductVO ) 
	{
		$ppmodel = new PapiWS_Model_PersonalizedProduct();
		$row = $ppmodel->find( $personalizedProductVO->personalizedProductId )->current();
		if ( count( $row )  ) {
			$row->creation_date = $personalizedProductVO->creationDate;
			$row->name = $personalizedProductVO->name;
			$row->template_product_id = $personalizedProductVO->templateProductId;
			$row->user_id = $personalizedProductVO->userId;
			$row->object = serialize( $personalizedProductVO );
			$row->save();
		} else {
			throw new Ext_Exception( 
				'Debe haber creado el producto previamente con createProduct()' 
			);
		}
		return true;
	}

	/**
	 * 
	 * Clona un producto a partir de otro
	 * 
	 * @param integer $personalizedProductId Id del producto a clonar
	 * @return integer Id del producto nuevo
	 */
	public function cloneProduct( $personalizedProductId ) 
	{
		$ppmodel = new PapiWS_Model_PersonalizedProduct();

		// buscamos producto a clonar
		$row = $ppmodel->find( $personalizedProductId )->current();
		if ( count( $row ) == 0 ) {
			throw new Ext_Exception( 
				'No existe el producto a clonar!' 
			);
		}

		// clonamos
		$newRow = $ppmodel->createRow();
		$newRow->creation_date = Ext_Db_Date::now();
		$newRow->name = $row->name;
		$newRow->template_product_id = $row->template_product_id;
		$newRow->user_id = $row->user_id;
		$newRow->object = $row->object;
		return $newRow->save();
	}
	/**
	 * 
	 * Congela en el filesystem el producto y sus objetos relacionados.
	 * 
	 * Persiste el producto y todos los objetos relacionados guardándolos en el 
	 * filesystem. Se debe especificar el producto, su dueño y un array de 
	 * opciones que definen qué objetos relacionados se almacenan. Las opciones 
	 * son: all, userimages, shapes, backgrounds o fonts.
	 * 
	 * @param integer $personalizedProductId Id del producto
	 * @param integer $owner Id de quien es el dueño
	 * @param array $options Opciones adicionales
	 * @return true si se graba exitosamente o una excepcion si hay errores.
	 */
	public function freezeProduct( $personalizedProductId, $ownerId, $options = array('userimages') ) 
	{
		// validate options
		$allOptions = array( 'userimages', 'shapes', 'backgrounds', 'fonts' );
		foreach( $options as $option ) {
			if ( ! in_array( $option, $allOptions ) ) {
				$msg = "Opcion [$option] no es valida. ";
				$msg .= "Los valores validos son: [";
				$msg .= implode( ", ", $allOptions );
				$msg .= "].";
				throw new Ext_Exception( $msg );
			}
		}
		// cargamos el producto y le ponemos el dueño si no lo tiene
		$prod = $this->getProduct( $personalizedProductId );
		if ( $prod->userId == null ) {
			$prod->userId = $ownerId;
		}

		if ( array_search( 'all', $options ) !== false ) {
			$options = $allOptions;
		}

		// freeze object to FS
		$this->freezeToStorage( $prod, $options );

		// save product info
		$this->saveProduct( $prod );
		return true;
	}

	private function freezeToStorage( $prod, $options ) 
	{
		foreach( $options as $option ) {
			$method = 'freeze' . ucfirst( $option );
			$this->$method( $prod );
		}
	}

	private function freezeUserimages( $prod )
	{
		foreach( $prod->faces as $face ) {
			foreach( $face->graphicalObjects as $go ) {
				if ( $go->type == PapiWS_Model_ShapeVO::SHAPE 
					&& $go->userImage ) {

					$uiservice = new PapiWS_Service_UserImage();
					$uiservice->freeze( $go, $prod->personalizedProductId );
				}
			}
		}
	}
	
	private function freezeBackgrounds( $prod )
	{
		throw new Ext_Exception( "freezeBackgrounds() not implemented." );
	}

	private function freezeShapes( $prod )
	{
		throw new Ext_Exception( "freezeShapes() not implemented." );
	}

	private function freezeFonts( $prod )
	{
		throw new Ext_Exception( "freezeFonts() not implemented." );
	}

	/**
	 * Agrega una Face al prdocuto
	 * 
	 * Borra un graphical Object
	 * 
	 * @param int PersonalizedProductId
	 * @param mixed $face Info del Face
	 * @return boolean true|false
	 */
	public function addFace( $personalizedProductId, $face)
	{
		$prod = getProduct( $personalizedProductId );
		$prod->faces[] = $face;
		return $prod;
	}

	/**
	 * Devuelve las caras de un producto
	 * 
	 * @param int PersonalizedProductId
	 * @return mixed Un PapiWS_Model_PersonalizedFaceVO con la cara.
	 */	
	public function getFaces( $personalizedProductId ) 
	{
		$prod = getProduct( $personalizedProductId );
		return $prod->faces;
	}

	private function _initPersonalizedProduct( $personalizedProductVo )
	{
		try{
			$pproduct = new PapiWS_Model_PersonalizedProduct();
			$pproduct->getAdapter()->setLobAsString(true);
			$row =  $pproduct->createRow();
			$row->template_product_id =  $personalizedProductVo->templateProductId;
			$row->creation_date = Ext_Db_Date::now();
			$row->object = serialize( $personalizedProductVo );
			return $row->save();
		} catch( Exception $e ){
			throw new Ext_Exception( 
				'No se pudo crear el Personalized Product: ' . $e->getMessage() 
			);
		}
	}

    // ----------------------------------------------------------------------
	//
	// Codigo muerto que en algun momento se podrá usar...
	//
	// TODO: this is a stub function while i read from the DB
	private function createDummyProduct( $personalizedProductId ) {

		$prod = new PapiWS_Model_PersonalizedProductVO();
		$prod->name = 'producto de prueba.';
		$prod->personalizedProductId = $personalizedProductId;
		$prod->faces = array();

		// levantamos el template 
		$tplService = new PapiWS_Service_ProductTemplate();
		$prod->templateProduct = $tplService->getInfo(10);

		// generamos las faces
		$f1 = new PapiWS_Model_PersonalizedFaceVO();
		$f1->faceOrder = 1;
		$f1->graphicalObjects = array();

		$f2 = new PapiWS_Model_PersonalizedFaceVO();
		$f2->faceOrder = 2;
		$f2->graphicalObjects = array();

		// agregamos un fondo a la primera cara
		$bg1 = new PapiWS_Model_BackgroundVO();
		$bg1->imageUrl = 'http://donline.ext.com.ar/sites/donline/files/gi4_0.jpg';
		$bg1->thumbnailUrl = 'http://donline.ext.com.ar/sites/donline/files/gi4.jpg';
		$bg1->type = PapiWS_Model_BackgroundVO::BACKGROUND_IMAGE;
		$bg1->x       = -180;
		$bg1->y       = -25;
		$bg1->width   = 266;
		$bg1->height  = 200;
		$bg1->fixedZ  = true;
		$f1->graphicalObjects[] = $bg1;

		// agregamos un fondo naranajaa la segunda cara
		$bg2 = new PapiWS_Model_BackgroundVO();
		$bg2->type = PapiWS_Model_BackgroundVO::BACKGROUND_FILL;
		$bg2->color = 0xff6600;
		$f2->graphicalObjects[] = $bg2;


		// agreguemos una shape a la parte de atrás
		$sh = new PapiWS_Model_ShapeVO();
		$sh->pngUrl = 'http://donline.ext.com.ar/sites/donline/files/icono5.png';
		$sh->swfUrl = 'http://donline.ext.com.ar/sites/donline/files/icono5.swf';
		$sh->svgUrl = 'http://donline.ext.com.ar/sites/donline/files/icono5.svg';
		$sh->x      = 50;
		$sh->y      = 60;
		$sh->z      = 1;
		$sh->width  = 128;
		$sh->height = 264;
		$f2->graphicalObjects[] = $sh;

		// agrego las dos caras
		$prod->faces[] = $f1;
		$prod->faces[] = $f2;

		return $prod;
	}
	
}
